package com.meida.module.bus.provider.api.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.StaticLog;
import com.alibaba.fastjson.util.TypeUtils;
import com.google.common.collect.Lists;
import com.meida.common.security.OpenHelper;
import com.meida.common.utils.RedisUtils;
import com.meida.module.admin.provider.service.BaseUserService;
import com.meida.module.bus.client.entity.BusOaApiExpLog;
import com.meida.module.bus.client.entity.BusOaApiLog;
import com.meida.module.bus.client.entity.srmapi.oa.BpmMainDo;
import com.meida.module.bus.client.entity.srmapi.oa.BusOaApprovalSync;
import com.meida.module.bus.client.entity.srmapi.oa.BusOaApprovalSyncDetail;
import com.meida.module.bus.client.entity.srmapi.psmtosrm.PMSResultBody;
import com.meida.module.bus.provider.api.PmsOaApi;
import com.meida.module.bus.provider.api.soap.SoapClient;
import com.meida.module.bus.provider.api.util.ApiConstants;
import com.meida.module.bus.provider.api.util.PmsOaUtil;
import com.meida.module.bus.provider.api.util.PmsApiUtil;
import com.meida.module.bus.provider.api.util.PmsLogUtil;
import com.meida.module.bus.provider.service.BusOaApprovalSyncDetailService;
import com.meida.module.bus.provider.service.BusOaApprovalSyncService;
import io.swagger.annotations.Api;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Collection;
import java.util.List;
import java.util.Map;

@Service
@RefreshScope
public class SyncOAService {
    @Autowired
    private PmsApiUtil pmsApiUtil;
    @Autowired
    private PmsOaUtil pmsOaUtil;
    @Autowired
    private PmsLogUtil pmsLogUtil;
    @Autowired
    private SyncOASubService syncOASubService;
    @Autowired
    private BusOaApprovalSyncService oaApprovalSyncService;
    @Autowired
    private BusOaApprovalSyncDetailService oaApprovalSyncDetailService;

    @Value("${oa.oa01Url}")
    private String oa01Url;
    @Value("${oa.oa02Url}")
    private String oa02Url;
    @Value("${oa.oa03Url}")
    private String oa03Url;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private PmsOaApiService pmsOaApiService;

    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private PmsOaApi pmsOaApi;
    @Autowired
    private BaseUserService userService;

    /**
     * 单点登录接口
     *
     * @param userNum 用户登陆名
     * @return 0 正常 1 异常
     */
    public int singleLogin(String userNum) {
        try {
            if (pmsApiUtil.oaConnectionCheck()) {
                return ApiConstants.LOGIN_OK;
            }

//            // 请求日志记录
//            BusOaApiLog busOaApiLog = new BusOaApiLog();
//            busOaApiLog.setUserNum(userNum);
//            busOaApiLog.setPmsFlow(ApiConstants.OAPMS01_LOG_MODEL_REQ);
//            pmsLogUtil.saveBusOaApiLog(busOaApiLog);
//            SoapClient client = SoapClient.create(oa01Url)
////             设置要请求的方法，此接口方法前缀为web，传入对应的命名空间
//                .setMethod("test", "webservice.xuch.interfaces.weaver.com.cn")
//                .setParam(userNum, userNum);
//
//            // 发送请求，参数true表示返回一个格式化后的XML内容
//            // 返回内容为XML字符串，可以配合XmlUtil解析这个响应
//            String res = client.send(true);
//            StaticLog.info(res, "INFO");
//            busOaApiLog = new BusOaApiLog();
//            busOaApiLog.setUserNum(userNum);
//            busOaApiLog.setFlowNum(ApiConstants.OAPMS01_LOG_MODEL_RES);
//            busOaApiLog.setCode(String.valueOf(ApiConstants.COMMON_RESULT_ZERO));
//            busOaApiLog.setMsg("");
//            pmsLogUtil.saveBusOaApiLog(busOaApiLog);

            return ApiConstants.LOGIN_OK;

        } catch (Exception ex) {
            ex.printStackTrace();
            BusOaApiExpLog busOaApiExpLog = new BusOaApiExpLog();
            busOaApiExpLog.setModel(ApiConstants.OAPMS01_LOG_MODEL_RES);
            busOaApiExpLog.setExceptionNm(ApiConstants.OAPMS01_LOG_MODEL_RES);
            busOaApiExpLog.setContent(ex.getMessage());
            return ApiConstants.LOGIN_ERROR;
        }

    }

    /**
     * PMS->OA 通用审批接口
     *
     * @param reqData     请求数据集合
     * @param approvalUrl 审批预览url
     * @param userNum     用户登陆名
     * @param appKind     各审批流调用参数列表
     *                    商务角色：工程量清单转100版本的审批   ApiConstants.BUSINESS_APPROVAL_100
     *                    商务角色：材料计划转200版本审批      ApiConstants.BUSINESS_APPROVAL_WZ_100
     *                    商务角色：分包计划转200版本审批      ApiConstants.BUSINESS_APPROVAL_FB_100
     *                    商务角色：分包合同下达审批           ApiConstants.BUSINESS_APPROVAL_FB_CONTACTS
     *                    商务角色：对外验工月报审批           ApiConstants.BUSINESS_APPROVAL_REPORT_OUT
     *                    <p>
     *                    【材料计划】
     *                    工程师角色：100版本_修正变更审批     ApiConstants.ENGINEER_APPROVAL_WZ_100_UPD
     *                    工程师角色：100版本_追加变更审批     ApiConstants.ENGINEER_APPROVAL_WZ_100_ADD
     *                    工程师角色：200版本_修正变更审批     ApiConstants.ENGINEER_APPROVAL_WZ_200_UPD
     *                    工程师角色：200版本_追加变更审批     ApiConstants.ENGINEER_APPROVAL_WZ_200_ADD
     *                    【分包计划】
     *                    工程师角色：100版本_修正变更审批     ApiConstants.ENGINEER_APPROVAL_FB_100_UPD
     *                    工程师角色：100版本_追加变更审批     ApiConstants.ENGINEER_APPROVAL_FB_100_ADD
     *                    工程师角色：200版本_修正变更审批     ApiConstants.ENGINEER_APPROVAL_FB_200_UPD
     *                    工程师角色：200版本_追加变更审批     ApiConstants.ENGINEER_APPROVAL_FB_200_ADD
     *                    <p>
     *                    工程师角色：材料计划申请_审批        ApiConstants.ENGINEER_APPROVAL_WZ_REQ
     *                    工程师角色：对内验工月报_审批        ApiConstants.ENGINEER_APPROVAL_FB_REQ
     * @param projectId   项目ID
     * @return OA审批即时返回结果
     * OA审批提交成功： ApiConstants.APPROVAL_SUCCESS
     * OA审批提交失败： ApiConstants.APPROVAL_FAIL
     */
    @SneakyThrows
    public int approval(Object reqData, String approvalUrl, String userNum, String appKind, String projectId) {
        StaticLog.info("OA审批流调用----approval---start");
        StaticLog.info("OA审批流调用----approval---reqData" + reqData);
        StaticLog.info("OA审批流调用----approval---approvalUrl" + approvalUrl);
        StaticLog.info("OA审批流调用----approval---userNum" + userNum);
        StaticLog.info("OA审批流调用----approval---projectId" + projectId);
        String majorCode = pmsOaApi.getMajorCodeByUserId(OpenHelper.getUserId());
        if (StrUtil.isNotEmpty(majorCode) && pmsOaApi.ckAppArovalStatus(reqData, userNum, Long.valueOf(projectId), majorCode, appKind)) {
            StaticLog.info("OA审批流调用----用户【" + userNum + "】专业【" + majorCode + "】已存在审核中的审批。" + projectId);
//            throw new Exception("OA审批流调用----用户【" + userNum + "】专业【" + majorCode + "】已存在审核中的审批。" + projectId);
        }
        // 请求日志记录
        BusOaApiLog busOaApiLog = new BusOaApiLog();
        busOaApiLog.setPmsFlow(appKind);
        String userName = userService.getByProperty("userName", userNum).getNickName();
        busOaApiLog.setUserNum(userNum);
        // 同步信息记录
        BusOaApprovalSync busOaApprovalSync = new BusOaApprovalSync();
        busOaApprovalSync.setAppKind(appKind);
        try {
            if (pmsApiUtil.oaConnectionCheck()) {
                syncOASubService.todoMake(Long.valueOf(projectId), appKind, reqData, userNum);
                return ApiConstants.APPROVAL_SUCCESS;
            }
            String workflowname = pmsOaUtil.getWorkflowname(appKind, 0);
            if (StrUtil.isEmpty(workflowname)) {
                syncOASubService.todoMake(Long.valueOf(projectId), appKind, reqData, userNum);
                return ApiConstants.APPROVAL_SUCCESS;
            }
            // 检查分包业务的专业代码，工程包代码
            if (pmsOaUtil.chkFbApprovalInfo(reqData, appKind)) {
                return ApiConstants.APPROVAL_FAIL;
            }

            busOaApprovalSync.setFlowNum(appKind);
            busOaApprovalSync.setProjectId(Long.valueOf(projectId));
            busOaApprovalSync.setUserNm(userNum);
            StaticLog.info("userNum---:" + busOaApprovalSync.getUserNm());
            approvalUrl = pmsOaUtil.getApprovlUrlBase() + approvalUrl;
            List<BusOaApprovalSyncDetail> syncOaDetailList = Lists.newArrayList();
            BpmMainDo bpmMainDo = syncOASubService.getApprovalObj(reqData, approvalUrl, userNum, appKind, projectId, syncOaDetailList, busOaApprovalSync);
            // 设定流程ID
            bpmMainDo.setApprovalNum(pmsOaUtil.getWorkflowname(appKind, 1));

            StaticLog.info("审批流发送信息：" + bpmMainDo.toString());
            StaticLog.info("审批发送开始");
            PMSResultBody oaResultBody = restTemplate.postForObject(pmsOaUtil.getOaBpmReqUrl(), bpmMainDo, PMSResultBody.class);
            StaticLog.info("审批流发送结果信息：" + oaResultBody.toString());
            StaticLog.info("审批发送结束");

            String requestId = String.valueOf(oaResultBody.getData());
            if (StrUtil.isNotEmpty(requestId) && !"null".equals(requestId)) {
                StaticLog.info("审批创建成功");
                busOaApprovalSync.setRequestId(Long.valueOf(requestId));
                busOaApprovalSync.setStatus(String.valueOf(ApiConstants.APPROVAL_ING));
                busOaApiLog.setApprovalStatus(ApiConstants.APPROVAL_ING);
                // redis设定
                StaticLog.info("redis---设定--start");
                StaticLog.info("approval--reqData:" + reqData);
                StaticLog.info("approval--requestId:" + requestId);
                StaticLog.info("approval--appKind:" + appKind);
                StaticLog.info("approval--projectId:" + projectId);
                StaticLog.info("approval--busOaApprovalSync:" + busOaApprovalSync);
                syncOASubService.setRedisForOaApproval(reqData, requestId, appKind, Long.valueOf(projectId), busOaApprovalSync);
                StaticLog.info("redis---设定--end");

            } else {
                StaticLog.info("审批创建失败");
                busOaApprovalSync.setStatus(String.valueOf(ApiConstants.APPROVAL_FAIL));
                busOaApiLog.setApprovalStatus(ApiConstants.APPROVAL_FAIL);
            }
            // 同步状态表
            oaApprovalSyncService.saveOrUpdate(busOaApprovalSync);
            syncOaDetailList.stream().forEach(sycnOaObj -> {
                BeanUtil.copyProperties(busOaApprovalSync, sycnOaObj);
                sycnOaObj.setBusOaApprovalSyncId(busOaApprovalSync.getId());

            });
            if (0 < syncOaDetailList.size()) {
                oaApprovalSyncDetailService.saveBatch(syncOaDetailList);
            }
            // 日志信息表
            pmsLogUtil.saveBusOaApiLog(busOaApiLog);

        } catch (Exception ex) {
            ex.printStackTrace();
            busOaApprovalSync.setStatus(String.valueOf(ApiConstants.APPROVAL_FAIL));
            oaApprovalSyncService.save(busOaApprovalSync);
            // 日志信息表
            busOaApiLog.setApprovalStatus(Integer.valueOf(ApiConstants.APPROVAL_FAIL));
            pmsLogUtil.saveBusOaApiLog(busOaApiLog);
            return Integer.valueOf(ApiConstants.APPROVAL_FAIL);
        }
        StaticLog.info("OA审批流调用----approval---end");
        return ApiConstants.APPROVAL_SUCCESS;
    }
}
